import { Sandpack } from '@/components'

# SuspenseQueries

Just as [`<SuspenseQuery/>`](/docs/react-query/SuspenseQuery) makes useSuspenseQuery easier to use in jsx, `<SuspenseQueries/>` serves to make useSuspenseQueries easier to use in jsx.

```jsx /SuspenseQueries/
import { SuspenseQueries } from '@suspensive/react-query'
import { Suspense, ErrorBoundary } from '@suspensive/react'
import { PostListItem, UserProfile } from '~/components'

const PostsPage = ({ userId }) => (
  <ErrorBoundary fallback={({ error }) => <>{error.message}</>}>
    <Suspense fallback="loading...">
      <SuspenseQueries
        queries={[userQueryOptions(userId), postsQueryOptions(userId)]}
      >
        {([{ data: user }, { data: posts }]) => (
          <>
            {<UserProfile {...user} />}
            {posts.map((post) => (
              <PostListItem key={post.id} {...post} />
            ))}
          </>
        )}
      </SuspenseQueries>
    </Suspense>
  </ErrorBoundary>
)
```

<Sandpack>

```tsx Example.tsx active
import { useState } from 'react'
import { SuspenseQueries } from '@suspensive/react-query'
import { Suspense, ErrorBoundary } from '@suspensive/react'
import { PostListItem } from './PostListItem'
import { UserProfile } from './UserProfile'
import { userQueryOptions, postsQueryOptions } from './queries'

export const Example = () => {
  const [userId, setUserId] = useState(1)

  return (
    <ErrorBoundary fallback={({ error }) => <>{error.message}</>}>
      <button onClick={() => setUserId((id) => id - 1)} disabled={userId === 1}>
        Previous User
      </button>
      <button
        onClick={() => setUserId((id) => id + 1)}
        disabled={userId === 10}
      >
        Next User
      </button>
      <Suspense fallback={<div>Loading...</div>}>
        <SuspenseQueries
          queries={[userQueryOptions(userId), postsQueryOptions(userId)]}
        >
          {([{ data: user }, { data: posts }]) => (
            <>
              <UserProfile {...user} />
              <ol>
                {posts.map((post) => (
                  <PostListItem key={post.id} {...post} />
                ))}
              </ol>
            </>
          )}
        </SuspenseQueries>
      </Suspense>
    </ErrorBoundary>
  )
}
```

```tsx PostListItem.tsx
import type { Post } from './api'

export const PostListItem = (props: Post) => {
  return <li style={{ marginBottom: '10px' }}>{props.title}</li>
}
```

```tsx UserProfile.tsx
import type { User } from './api'

export const UserProfile = (props: User) => {
  return (
    <div style={{ padding: '16px' }}>
      <h1>{props.name}</h1>
      <p>{props.email}</p>
      <p>{props.phone}</p>
    </div>
  )
}
```

```tsx queries.ts
import { queryOptions } from '@suspensive/react-query'
import { getPosts, getUser } from './api'

export const userQueryOptions = (userId: number) =>
  queryOptions({
    queryKey: ['users', userId],
    queryFn: () => getUser(userId),
  })

export const postsQueryOptions = (userId: number) =>
  queryOptions({
    queryKey: ['users', userId, 'posts'],
    queryFn: () => getPosts(userId),
  })
```

```tsx api.ts
export type Post = {
  userId: number
  id: number
  title: string
  body: string
}

export const getPosts = async (userId: number): Promise<Post[]> => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/posts?userId=${userId}`
  )

  if (!response.ok) {
    throw new Error('An error occurred')
  }

  const data = await response.json()

  return data
}

export type User = {
  id: number
  name: string
  username: string
  email: string
  address: {
    street: string
    suite: string
    city: string
    zipcode: string
    geo: {
      lat: string
      lng: string
    }
  }
  phone: string
  website: string
  company: {
    name: string
    catchPhrase: string
    bs: string
  }
}

export const getUser = async (id: number): Promise<User> => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/users/${id}`
  )

  if (!response.ok) {
    throw new Error('An error occurred')
  }

  const data = await response.json()

  return data
}
```

</Sandpack>

### Version History

| Version  | Changes                                                                                                                                   |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `v3.0.0` | `networkMode` has been fixed to `'always'`. For more details, please refer to the [Migration to v3 guide](./migration/migrate-to-v3.mdx). |
